const { app, BrowserWindow, ipcMain, session, screen, dialog, shell } = require('electron');
const WinState = require('electron-win-state').default
const { log, error } = require('console');
const AdmZip = require('adm-zip');
const path = require('path')
const fs = require('fs').promises;

// 是否是开发模式
let dev = true;
// 打包状态自动取消开发者模式（防止异常进入开发者模式）
if (app.isPackaged) {
    dev = false;
}
// 默认配置
const defaultSetting = {
    download: app.getAppPath() + "\\默认下载",
    name: "测试数据",
}
const settingPath = app.getAppPath() + "\\setting.json";
// 默认窗口状态
const winState = new WinState({
    defaultWidth: 1200,
    defaultHeight: 750,
})
// 代理映射
const proxyMap = {
    serverURL: 'http://127.0.0.1:8081',
    fileServerURL: 'http://127.0.0.1:10001/download?fileName=',
}

let win = null;
let userSetting;

// 创建主窗口
const createWindow = () => {
    win = new BrowserWindow({
        ...winState.winOptions,

        frame: false,
        show: false,
        alwaysOnTop: true,
        icon: path.resolve(__dirname, '../../build/icon.ico'),

        webPreferences: {
            preload: path.resolve(__dirname, '../preload/index.js'),
        }
    })

    if (dev) {
        console.log("is dev --mainWin");
        win.loadURL('http://127.0.0.1:7001/')
    } else {
        win.loadFile(path.resolve(__dirname, '../renderer/index.html'))
    }

    const wc = win.webContents
    // wc.openDevTools()

    win.on('ready-to-show', () => {
        win.show()
        win.setAlwaysOnTop(false)
        if (!dev) {
            // 触发动态路由
            win.webContents.send('updateRoute', "/");
        }
    })

    winState.manage(win)
}
// 获取用户配置
const getUserSetting = async function () {

    try {
        const userSettingJson = await fs.readFile(settingPath, 'utf8');
        userSetting = JSON.parse(userSettingJson)
    } catch (err) {
        console.error(err);
        if (err.code === 'ENOENT') {
            // 补充默认配置
            userSetting = defaultSetting
            console.error('setting file ENOENT, use default setting');
            const defaultSettingJson = JSON.stringify(defaultSetting)
            await fs.writeFile(settingPath, defaultSettingJson, (err) => {
                console.error(err);
                return;
            })
            console.log('write default setting success');
        } else {
            throw err;
        }
    } finally {
        fs.mkdir(userSetting.download, { recursive: true })

    }

}

// 启动初始化
app.whenReady().then(() => {
    createWindow()

    getUserSetting()


    // 监听网络请求  
    session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
        const url = details.url;
        console.log(url);
        if (url.startsWith("file:///api")) {
            const api = url.substring("file:///api".length);
            console.log('---serverURL redirect: ', api);
            // 重定向请求  
            callback({ redirectURL: proxyMap.serverURL + api });

        } else if (url.startsWith("file:///filePath")) {
            let api = url.substring("file:///filePath".length);
            api = encodeURIComponent(decodeURIComponent(api));
            console.log('---fileServerURL redirect: ', api);
            // 重定向请求  
            callback({ redirectURL: proxyMap.fileServerURL + api });
        } else {
            // 方行
            callback({ cancel: false });
        }
    });

    // 监听 will-download 事件  
    session.defaultSession.on('will-download', (event, item, webContents) => {
        // 设置下载文件的保存路径  
        item.setSavePath(userSetting.download + "\\" + item.getFilename());
        console.log(item.getSavePath());
        win.webContents.send('download-task-notifies', "新增下载任务", "目标文件：" + item.getFilename());

        // 监听下载进度  
        item.on('updated', (event, state) => {
            if (state === 'interrupted') {
                console.log('interrupted');
                win.webContents.send('download-task-notifies', "下载任务中断", "目标文件：" + item.getFilename());
            } else if (state === 'progressing') {
                if (item.isPaused()) {
                    console.log('Paused');
                } else {
                    console.log(`Received Bytes : ${item.getReceivedBytes()}`);
                }
            }
        });

        // 监听下载完成事件  
        item.once('done', (event, state) => {
            // 下载完成
            if (state === 'completed') {
                console.log(`success: ${item.getSavePath()}`);
                win.webContents.send('download-task-notifies', "下载任务已完成", "目标文件：" + item.getFilename() + "<br>已保持至预定的下载目录");
            } else {
                console.log(`failed : ${state}`);
                if (state === "cancelled") {
                    win.webContents.send('download-task-notifies', "下载任务已取消", "已取消保存的文件：" + item.getFilename());
                    return;
                }
                win.webContents.send('download-task-notifies', "下载任务已中断", "状态码：" + state);
            }
        });
    });
})
app.on('window-all-closed', function () {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

// 交互事件
ipcMain.handle('winMinimize', () => {
    win.minimize();
})
ipcMain.handle('winMaximize', () => {
    if (win.isMaximized()) {
        win.unmaximize();
    } else {
        win.maximize();
    }
    // 或者简单地使用 toggleMaximize 方法，如果存在的话  
    // win.toggleMaximize();  
});
ipcMain.handle('winClose', () => {
    win.close();
    win = null
});

ipcMain.handle('defaultSize', () => {
    win.setSize(winState.opts.defaultWidth, winState.opts.defaultHeight, true)
});
ipcMain.handle('centerWindow', () => {
    centerWindow(win)
});
ipcMain.handle('restart', () => {
    win.close()
    win = null
    createWindow()
});

//文件操作
ipcMain.handle('getUserSetting', async () => {
    if (userSetting) {
        return userSetting;
    } else {
        await getUserSetting();
        return userSetting;
    }
})
ipcMain.handle('getDirPath', async () => {
    let filePath = undefined
    try {
        const result = await
            dialog.showOpenDialog({
                title: '选择文件夹',
                properties: ['openDirectory'],
            })

        filePath = result.filePaths[0]

    } catch (err) {
        console.log(err);
    }
    // console.log('filePath: ' + filePath);
    return filePath
})
ipcMain.handle('getFilePath', async (event, filters = [{ name: 'All Files', extensions: ['*'] }]) => {
    let filePath = undefined
    try {
        const result = await
            dialog.showOpenDialog({
                title: '选择文件',
                filters: filters,
                properties: ['openFile'],
                defaultPath: userSetting.download,
            })
        filePath = result.filePaths[0]
    } catch (err) {
        console.log(err);
    }
    console.log('filePath: ' + filePath);
    return filePath
})
ipcMain.handle('modifySetting', async (event, key, value) => {
    const fileName = app.getAppPath() + "\\resources\\setting.json";
    try {
        userSetting[key] = value
        await fs.writeFile(fileName, JSON.stringify(userSetting))
        getUserSetting()
    } catch (err) {
        console.error(err);
    }
})
ipcMain.handle('download', async (event, downloadURL) => {
    // downloadURL = "http://127.0.0.1:10001/getFile?fileName=/images/%E4%B8%BA%E7%BE%8E%E5%A5%BD%E7%9A%84%E4%B8%96%E7%95%8C%E7%8C%AE%E4%B8%8A%E7%A5%9D%E7%A6%8F%EF%BC%81/cover.png"
    // downloadURL = "http://127.0.0.1:10001/getFile?fileName=/novels/%E4%B8%BA%E7%BE%8E%E5%A5%BD%E7%9A%84%E4%B8%96%E7%95%8C%E7%8C%AE%E4%B8%8A%E7%A5%9D%E7%A6%8F%EF%BC%81/%E7%AC%AC%E4%B8%80%E5%8D%B7.epub"
    console.log(downloadURL);
    downloadURL = proxyMap.fileServerURL + downloadURL.substring("/filePath".length);;
    win.webContents.downloadURL(downloadURL);
})
ipcMain.handle('open', (event, filePath) => {
    shell.openPath(filePath)
})
ipcMain.handle('getImagesBase64', (event, filePath) => {
    return new Promise((resolve, reject) => {
        const zip = new AdmZip(filePath);
        const imagesBase64 = [];
        console.log("zip new successfully");

        const debounce = function (func, wait = 300) {
            let timeout;
            return function () {
                const context = this;
                const args = arguments;
                clearTimeout(timeout);
                timeout = setTimeout(() => func.apply(context, args), wait);
            };
        }
        const de_resolve = debounce(
            (result) => {
                console.log("resolve ");
                resolve(result);
            }
        )
        const getMimeType = function (filename) {
            const fileExtension = filename.split('.').pop().toLowerCase();
            let mimeType = 'application/octet-stream';
            const mimeTypes = {
                'jpg': 'image/jpeg',
                'jpeg': 'image/jpeg',
                'png': 'image/png',
                'gif': 'image/gif',
            };
            if (mimeTypes[fileExtension]) {
                mimeType = mimeTypes[fileExtension];
            }
            return mimeType;
        }
        const entryToBase64 = function (entry) {
            if (entry.isDirectory) {
                entry.getEntries().forEach(e => entryToBase64(e))
            } else if (/\.(jpg|jpeg|png|gif)$/i.test(entry.name)) {
                const data = zip.readFile(entry);
                const base64Data = Buffer.from(data, 'binary').toString('base64');
                const base64Image = `data:${getMimeType(entry.name)};base64,${base64Data}`;
                imagesBase64.push(base64Image);
                de_resolve(imagesBase64);
            }
        }

        zip.getEntries().forEach(e => entryToBase64(e))

    })
})
ipcMain.handle('getArrayBuffer', async (event, filePath) => {
    console.log('filePath: ' + filePath);

    const buffer = await fs.readFile(filePath, { encoding: null });

    // 转换Buffer为Uint8Array  
    const uint8Array = new Uint8Array(buffer);

    // Uint8Array的.buffer属性就是ArrayBuffer  
    const arrayBuffer = uint8Array.buffer;

    // 现在你可以使用arrayBuffer了  
    return arrayBuffer;

})
ipcMain.handle('pdfConvert', async (event, info) => {
    console.log(info);
    const { jsPDF } = require('jspdf');
    const sharp = require('sharp');
    const AdmZip = require('adm-zip');

    const createPdfFromZip = async (zipPath, outputPath) => {
        // 读取ZIP文件
        const zip = new AdmZip(zipPath);
        const zipEntries = zip.getEntries();

        // 过滤出图片文件
        const imageEntries = zipEntries.filter(entry =>
            ['.jpg', '.jpeg', '.png'].includes(path.extname(entry.entryName).toLowerCase())
        );

        // 创建一个新的PDF文档
        const doc = new jsPDF();

        for (const entry of imageEntries) {
            // 从ZIP文件中读取图片数据
            const imageBuffer = entry.getData();

            // 使用sharp获取图片尺寸
            const { width, height } = await sharp(imageBuffer).metadata();

            // 计算缩放比例以适应A4纸张
            const ratio = Math.min(doc.internal.pageSize.getWidth() / width, doc.internal.pageSize.getHeight() / height);
            const imgWidth = width * ratio;
            const imgHeight = height * ratio;

            // 将图片添加到PDF
            doc.addImage(imageBuffer, 'JPEG', (doc.internal.pageSize.getWidth() - imgWidth) / 2, 0, imgWidth, imgHeight);

            // 如果不是最后一个图片，则添加新页
            if (imageEntries.indexOf(entry) < imageEntries.length - 1) {
                doc.addPage();
            }
        }

        // 保存PDF
        doc.save(outputPath);

    }

    const zipPath = info.filePath;
    const outputPath = userSetting.download + '\\' + info.filePath.split('\\').pop().split('.')[0] + '.pdf';

    createPdfFromZip(zipPath, outputPath)
        .then(() => console.log('PDF created successfully!'))
        .catch(err => console.error('Error creating PDF:', err));


    return outputPath;

})



// 将窗口移动到屏幕中央的函数  
const centerWindow = function (window) {
    const display = screen.getPrimaryDisplay() // 获取主屏幕  
    const windowBounds = window.getBounds() // 获取窗口当前的大小  

    // 计算窗口左上角应该放置的 x, y 坐标  
    const x = Math.floor((display.workArea.width - windowBounds.width) / 2)
    const y = Math.floor((display.workArea.height - windowBounds.height) / 2)

    // 将窗口移动到计算出的位置  
    window.setPosition(x, y)
}

let cw;
let nw;
// 工具窗口
ipcMain.handle('cartoonWatcher', (event, info) => {
    if (cw && !cw.isDestroyed()) cw.close();
    cw = new BrowserWindow({
        width: 800,
        height: 800,

        frame: false,
        show: false,
        alwaysOnTop: true,

        webPreferences: {
            preload: path.resolve(__dirname, '../preload/index.js'),
        }
    })


    if (dev) {
        console.log("is dev --cartoonWatcher");
        if (info.filePath) {
            const filePath = info.filePath.replaceAll('\\', '|');
            cw.loadURL('http://127.0.0.1:7001/cartoonWatcher/local/' + filePath)
        } else {
            cw.loadURL('http://127.0.0.1:7001/cartoonWatcher/' + info.cid + '/' + info.chapterName)
        }
    } else {
        cw.loadFile(path.resolve(__dirname, '../renderer/index.html'))
    }



    cw.on('ready-to-show', () => {
        cw.show();
        cw.setAlwaysOnTop(false);

        if (!dev) {
            let path;
            if (info.filePath) {
                const filePath = info.filePath.replaceAll('\\', '|');
                path = '/cartoonWatcher/local/' + filePath;
            } else {
                path = '/cartoonWatcher/' + info.cid + '/' + info.chapterName;
            }
            // 触发动态路由
            cw.webContents.send('updateRoute', path);
        }


    })

    return true;
});
ipcMain.handle('novelWatcher', async (event, info) => {
    if (nw && !nw.isDestroyed()) nw.close();
    nw = new BrowserWindow({
        width: 800,
        height: 800,

        frame: false,
        show: false,
        alwaysOnTop: true,

        webPreferences: {
            preload: path.resolve(__dirname, '../preload/index.js'),
        }
    })

    if (dev) {
        console.log("is dev --novelWatcher");
        if (info.filePath) {
            const filePath = info.filePath.replaceAll('\\', '|');
            nw.loadURL('http://127.0.0.1:7001/novelWatcher/local/' + filePath)
        } else {
            nw.loadURL('http://127.0.0.1:7001/novelWatcher/' + info.nid + '/' + info.chapterName)
        }
    } else {
        nw.loadFile(path.resolve(__dirname, '../renderer/index.html'))
    }


    nw.on('ready-to-show', () => {
        nw.show();
        nw.setAlwaysOnTop(false);
        if (!dev) {
            let path;
            if (info.filePath) {
                const filePath = info.filePath.replaceAll('\\', '|');
                path = '/novelWatcher/local/' + filePath;
            } else {
                path = '/novelWatcher/' + info.nid + '/' + info.chapterName;
            }
            // 触发动态路由
            nw.webContents.send('updateRoute', path);
        }
    })

    return true;
});

// 交互事件
ipcMain.handle('minimize', (e) => {
    BrowserWindow.getFocusedWindow().minimize()
});
ipcMain.handle('maximize', () => {
    const currentWin = BrowserWindow.getFocusedWindow().minimize();
    if (currentWin.isMaximized()) {
        currentWin.unmaximize();
    } else {
        currentWin.maximize();
    }
});
ipcMain.handle('close', (e) => {
    BrowserWindow.getFocusedWindow().close();
});


